package main

import (
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"miracle-recorder/internal/config"
	"miracle-recorder/internal/database"
	"miracle-recorder/internal/handlers"
	"miracle-recorder/internal/middleware"
	"miracle-recorder/internal/services"
	"miracle-recorder/internal/websocket"

	"github.com/gin-gonic/gin"
	"github.com/rs/cors"
)

func main() {
	// 加载配置
	cfg, err := config.LoadConfig()
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	// 初始化数据库
	db, err := database.InitDB(cfg)
	if err != nil {
		log.Fatalf("Failed to initialize database: %v", err)
	}
	defer db.Close()

	// 初始化Redis
	redisClient, err := database.InitRedis(cfg)
	if err != nil {
		log.Fatalf("Failed to initialize Redis: %v", err)
	}
	defer redisClient.Close()

	// 初始化服务
	userService := services.NewUserService(db, redisClient)
	topicService := services.NewTopicService(db, redisClient)
	livestreamService := services.NewLivestreamService(db, redisClient)
	aiService := services.NewAIService(cfg.AIService.URL)
	uploadService := services.NewUploadService(cfg.Upload.Path)

	// 初始化处理器
	userHandler := handlers.NewUserHandler(userService)
	topicHandler := handlers.NewTopicHandler(topicService)
	livestreamHandler := handlers.NewLivestreamHandler(livestreamService)
	aiHandler := handlers.NewAIHandler(aiService)
	uploadHandler := handlers.NewUploadHandler(uploadService)

	// 初始化WebSocket管理器
	wsManager := websocket.NewManager()

	// 设置Gin模式
	if cfg.Log.Level == "debug" {
		gin.SetMode(gin.DebugMode)
	} else {
		gin.SetMode(gin.ReleaseMode)
	}

	// 创建路由
	router := gin.Default()

	// 中间件
	router.Use(middleware.Logger())
	router.Use(middleware.CORS(cfg.CORS))
	router.Use(middleware.Recovery())

	// 健康检查
	router.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"status": "healthy", "timestamp": time.Now().UTC()})
	})

	// API路由组
	api := router.Group("/api/v1")
	{
		// 用户相关路由
		auth := api.Group("/auth")
		{
			auth.POST("/register", userHandler.Register)
			auth.POST("/login", userHandler.Login)
			auth.POST("/refresh", userHandler.RefreshToken)
		}

		// 需要认证的路由
		authenticated := api.Group("/")
		authenticated.Use(middleware.JWTAuth(cfg.JWT.Secret))
		{
			// 用户信息
			authenticated.GET("/user/profile", userHandler.GetProfile)
			authenticated.PUT("/user/profile", userHandler.UpdateProfile)

			// 话题相关
			authenticated.GET("/topics", topicHandler.ListTopics)
			authenticated.POST("/topics", topicHandler.CreateTopic)
			authenticated.GET("/topics/:id", topicHandler.GetTopic)
			authenticated.PUT("/topics/:id", topicHandler.UpdateTopic)
			authenticated.DELETE("/topics/:id", topicHandler.DeleteTopic)

			// 直播相关
			authenticated.GET("/livestreams", livestreamHandler.ListLivestreams)
			authenticated.POST("/livestreams", livestreamHandler.CreateLivestream)
			authenticated.GET("/livestreams/:id", livestreamHandler.GetLivestream)
			authenticated.PUT("/livestreams/:id", livestreamHandler.UpdateLivestream)
			authenticated.DELETE("/livestreams/:id", livestreamHandler.DeleteLivestream)
			authenticated.POST("/livestreams/:id/start", livestreamHandler.StartLivestream)
			authenticated.POST("/livestreams/:id/stop", livestreamHandler.StopLivestream)

			// 文件上传
			authenticated.POST("/upload", uploadHandler.UploadFile)
			authenticated.GET("/upload/:filename", uploadHandler.DownloadFile)

			// AI相关
			authenticated.POST("/ai/summarize", aiHandler.SummarizeContent)
			authenticated.POST("/ai/generate-solution", aiHandler.GenerateSolution)
		}

		// WebSocket路由
		api.GET("/ws", func(c *gin.Context) {
			userID := c.Query("user_id")
			topicID := c.Query("topic_id")
			wsManager.HandleConnection(c.Writer, c.Request, userID, topicID)
		})
	}

	// 启动WebSocket管理器
	go wsManager.Run()

	// 创建HTTP服务器
	server := &http.Server{
		Addr:    ":" + cfg.Server.Port,
		Handler: router,
	}

	// 优雅关闭
	go func() {
		log.Printf("Server starting on port %s", cfg.Server.Port)
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("Failed to start server: %v", err)
		}
	}()

	// 等待中断信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	log.Println("Server is shutting down...")

	// 优雅关闭服务器
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	if err := server.Shutdown(ctx); err != nil {
		log.Printf("Server forced to shutdown: %v", err)
	}

	log.Println("Server exited")
}